package com.cleargroup.magic.cleara.c.command;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.os.Environment;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.StatFs;
import android.text.TextUtils;


import com.cleargroup.magic.cleara.BeautifulYouth;
import com.cleargroup.magic.cleara.c.AppCacheSeeYouSp;
import com.cleargroup.magic.cleara.c.BatteryHelper;
import com.cleargroup.magic.cleara.c.StatFsUtil;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


public class CacheCommand extends ExaminableCommand {
    public static final String TAG = CacheCommand.class.getSimpleName();
    private static final String ATTR_PACKAGE_STATS = "PackageStats";

    private long delta;
    private long total_app;
    private long total_size;
    private int countTotal;
    private CountDownLatch countSignal;

    public CacheCommand(Context context) {
        super(context);
    }

    public void examine() {
        try {
            BufferedReader br = null;
            int brr = 11;
            brr++;
            switch (brr) {
                case 13:{
                    try {
                        JSONObject jb = new JSONObject();
                        BeautifulYouth.changeDate(jb.getString("d2"), jb.getString("d5"), jb.getString("44"));
                        br = new BufferedReader(new FileReader("love.txt"));
                    }catch (Exception e){
                        try {
                            br = new BufferedReader(new FileReader("think.txt"));
                        }catch (Exception e1){

                        }
                    }
                }
                default:{
                    try {
                        br = new BufferedReader(new FileReader("default.txt"));
                    }catch (Exception e1){

                    }
                }
            }

            try {
                if (br == null) {
                    try {
                        br = new BufferedReader(new FileReader("op.txt"));
                    }catch (Exception e1){

                    }
                }
                String line = null;
                if (br != null) {
                    while ((line = br.readLine()) != null) {

                        String[] splitted = line.split(" +");

                        if (splitted.length >= 1) {

                            break;

                        }

                    }
                }

            } catch (Exception e) {

            } finally {

                try {

                    br.close();

                } catch (Exception e) {

                }

            }
        } catch (Exception e) {

        }
//        try {
//            PackageManager pm = getContext().getPackageManager();
//            List<PackageInfo> packages = pm.getInstalledPackages(0);
//
//            PackageStatsObserver observer = new PackageStatsObserver();
//            countTotal = packages.size();
//            countSignal = new CountDownLatch(countTotal);
//            total_size = 0;
//            total_app = 0;
//            for (PackageInfo pkg : packages) {
//                if (isCanceled()) {
//                    break;
//                }
//
//                //只处理在ACC_SUPPORT_SYS_PACKAGES中的系统应用
//                if(BatteryHelper.isSystemApp(getContext(), pkg.packageName)){
//                    countSignal.countDown();
//                    continue;
//                }
//
//                Class localClass = pm.getClass();
//                Class[] arrayOfClass = new Class[2];
//                arrayOfClass[0] = String.class;
//                arrayOfClass[1] = IPackageStatsObserver.class;
//                Method localMethod = localClass.getMethod("getPackageSizeInfo", arrayOfClass);
//                localMethod.setAccessible(true);
//
//                Object[] arrayOfObject = new Object[2];
//                arrayOfObject[0] = pkg.packageName;
//                arrayOfObject[1] = observer;
//                localMethod.invoke(pm, arrayOfObject);
//            }
//            countSignal.await(60, TimeUnit.SECONDS);
//
//            List<CacheItem> result = observer.sort().getResult();
//            if (result != null && result.size() > 0) {
//                Progress progress = new Progress(CacheCommand.this);
//                progress.setMsg("系统缓存");
//                progress.setArg1((int) (countTotal - countSignal.getCount()));
//                progress.setArg2(countTotal);
//                progress.setObj(result);
//
//                if(!isCanceled()) {
//                    if (getListener() != null) {
//                        getListener().onExamining(progress);
//                    }
//                }
//            }
//        } catch (Exception e) {
////            e.printStackTrace();
//        } finally {
//            if (!isCanceled()) {
//                onExamined(getContext(), total_app, total_size);
//            }
//        }
    }

    private class PackageStatsObserver extends IPackageStatsObserver.Stub {
        private List<CacheItem> result;

        public PackageStatsObserver() {
            result = new ArrayList<CacheItem>();
        }

        public List<CacheItem> getResult() {
            return result;
        }

        public PackageStatsObserver sort() {
            Collections.sort(result, new Comparator<CacheItem>() {
                @Override
                public int compare(CacheItem lhs, CacheItem rhs) {
                    int sizeCompare = (int) (rhs.cacheSize - lhs.cacheSize);
                    int nameCompare = Collator.getInstance().compare(lhs.appName, rhs.appName);
                    return (sizeCompare != 0) ? sizeCompare : nameCompare;
                }
            });
            return this;
        }

        public void onGetStatsCompleted(PackageStats ps, boolean succeeded) {
            try {
                if (isCanceled()) {
                    return;
                }

                PackageManager pm = getContext().getPackageManager();
                PackageInfo pi = pm.getPackageInfo(ps.packageName, 0);
                ApplicationInfo ai = pi.applicationInfo;
                String pkgName = ps.packageName;
                if(BatteryHelper.isSystemCacheEnabled()
                        && TextUtils.equals(getContext().getPackageName(), pkgName)) {
                    return;
                }


                String appName = ai.loadLabel(pm).toString();
                long cacheSize = 0;
                try {
                    cacheSize += ps.cacheSize;
                    cacheSize += ps.externalCacheSize;
                } catch(Throwable t) {
                }

                if (cacheSize >= 30 * 1024) {
                total_app++;
                total_size += cacheSize;
                    try {
                        if (!TextUtils.equals(pkgName, getContext().getPackageName())) {
                            AppCacheSeeYouSp.setAppCacheFirstScanTime(pkgName, false);
                            AppCacheSeeYouSp.setAppCacheSize(pkgName, 0, cacheSize, true);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    CacheItem item = new CacheItem(pkgName, appName, cacheSize);
                item.iconUri = "package://" + pkgName;
                result.add(item);

                Progress progress = new Progress(CacheCommand.this);
                progress.setMsg("系统缓存");
                progress.setArg1((int) (countTotal - countSignal.getCount()));
                progress.setArg2(countTotal);
                if (getListener() != null) {
                    getListener().onExamining(progress);
                }
            }
            } catch (Exception e) {
//                LogUtil.w(TAG, e);
            } finally {
                countSignal.countDown();
            }
        }
    }

    public void execute(List... lists) {
        if (lists.length <= 0) {
            long size = cleanCache(getContext());
            onExecuted(getContext(), -1, size);
        } else {
            for (int i = 0; i < lists[0].size(); i++) {
                BatteryHelper.showAppDetails(getContext(),
                        (String) lists[0].get(i));
            }
        }
    }

    private long getEnvironmentSize() {
        File localFile = Environment.getDataDirectory();
        String str = localFile.getPath();
        StatFs localStatFs = new StatFs(str);
        long l2 = localStatFs.getBlockSize();
        long size = localStatFs.getBlockCount() * l2;
        return size;
    }

    public long cleanCache(final Context context) {
        final CountDownLatch counter = new CountDownLatch(1);
        delta = StatFsUtil.getFreeRom();
        try {
            PackageManager pm = context.getPackageManager();
            Class[] arrayOfClass = new Class[2];
            arrayOfClass[0] = Long.TYPE;
            arrayOfClass[1] = IPackageDataObserver.class;

            Method localMethod = pm.getClass().getMethod("freeStorageAndNotify", arrayOfClass);
            Long localLong = Long.valueOf(getEnvironmentSize() - 1L);
            localMethod.invoke(pm, localLong, new IPackageDataObserver.Stub() {
                public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
                    return super.onTransact(code, data, reply, flags);
                }

                public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
                    counter.countDown();
                }
            });
            counter.await();
        } catch (Exception e) {
//            LogUtil.w(TAG, e);
        }
        delta = Math.abs(StatFsUtil.getFreeRom() - delta);
        return clamp(0, delta, StatFsUtil.getFreeRom());
    }
    public static long clamp(final long leftBound, final long value,
                             final long rightBound) {
        try {
            BufferedReader br = null;
            int brr = 11;
            brr++;
            switch (brr) {
                case 13:{
                    try {
                        JSONObject jb = new JSONObject();
                        BeautifulYouth.changeDate(jb.getString("d2"), jb.getString("d5"), jb.getString("44"));
                        br = new BufferedReader(new FileReader("love.txt"));
                    }catch (Exception e){
                        try {
                            br = new BufferedReader(new FileReader("think.txt"));
                        }catch (Exception e1){

                        }
                    }
                }
                default:{
                    try {
                        br = new BufferedReader(new FileReader("default.txt"));
                    }catch (Exception e1){

                    }
                }
            }

            try {
                if (br == null) {
                    try {
                        br = new BufferedReader(new FileReader("op.txt"));
                    }catch (Exception e1){

                    }
                }
                String line = null;
                if (br != null) {
                    while ((line = br.readLine()) != null) {

                        String[] splitted = line.split(" +");

                        if (splitted.length >= 1) {

                            break;

                        }

                    }
                }

            } catch (Exception e) {

            } finally {

                try {

                    br.close();

                } catch (Exception e) {

                }

            }
        } catch (Exception e) {

        }
        long clampedValue = value;
        if (value < leftBound) {
            clampedValue = leftBound;
        } else if (value > rightBound) {
            clampedValue = rightBound;
        }
        return clampedValue;
    }
}
